home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / DISK / AFF0917.ARJ / BROWSE.ASM < prev    next >
Assembly Source File  |  1991-02-24  |  16KB  |  508 lines

  1. ;    BROWSE.ASM -- Full Screen File Pager
  2. ;    ====================================
  3.  
  4. CSEG        Segment
  5.         Assume    CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
  6.         Org    0080h
  7. Parameter    Label    Byte
  8.         Org    0100h
  9. Entry:        Jmp Begin
  10.  
  11. ;    All Data
  12. ;    --------
  13.  
  14.         db    'ATTR='
  15. Attribute    db    0        ; Current screen attribute
  16.         db    'SHIFT='
  17. ShiftHoriz    db    8        ; Horizontal shift screen default
  18. DosVersionFail    db    'Requires DOS 2.0 or above$'
  19. NoSpaceFail    db    'Not enough memory$'
  20. FileFail    db    'File Not Found$'
  21. ScreenFail    db    'Unsupported video mode$'
  22. Delimiters    db    9,' ,;=/'    ; Delimiters in parameter
  23. FileHandle    dw    ?        ; Use for saving file handle
  24. WSMode        db    0FFh        ; AND value for non-WordStar mode
  25. LineLength    db    ?        ; Length of line (from BIOS)
  26. NumberLines    db    25,0        ; Number of lines (check EGA BIOS)
  27. ScreenSize    dw    ?        ; Size of screen in bytes
  28. CheckRetrace    db    1        ; Flag zero if EGA or MONO used
  29. Addr6845    dw    ?        ; Could use for retrace check    
  30. ScreenAddr    Label    DWord        ; Address of screen
  31. ScreenOff    dw    0        ; Higher for non-page 0
  32. ScreenSeg    dw    0B800h        ; Set to B000h for Mono Mode 7
  33. ScreenStart    dw    ?        ; Points within buffer 
  34. EndOfFile    dw    ?        ; Points within buffer
  35. FileOffset    dw    -1, -1        ; Address within file of buffer data
  36. HorizOffset    dw    0        ; Horizontal offset for display    
  37. RightMargin    dw    0        ; Right margin for offset display
  38. Dispatch    dw    Home, Up, PgUp, Dummy, Left
  39.         dw    Dummy, Right, Dummy, EndKEY, Down, PgDn
  40.  
  41. ;    Check DOS Version for 2.0 or above
  42. ;    ----------------------------------
  43.  
  44. Begin:        Cld            ; All string directions forward
  45.         Mov    AH,30h
  46.         Int    21h        ; Get DOS Version Number
  47.         Cmp    AL,2        ; Check for 2.0 or later
  48.         Jae    DOSVerOK
  49.         Mov    DX,Offset DOSVersionFail
  50. ErrorExit:    Mov    AH,9        ; Write error message
  51.         Int    21h
  52.         Int    20h
  53.  
  54. ;    Parse Command Line to get File Name and WordStar flag
  55. ;    -----------------------------------------------------
  56.  
  57. DOSVerOK:    Mov    SI,1 + Offset Parameter    ; Points to parameter
  58. NameSearch:    Lodsb                ; Get byte
  59.         Cmp    AL,13            ; Check if carriage return
  60.         Jz    NoFileFound        ; If so, no file name
  61.         Mov    DI,Offset Delimiters    ; String of delimiters
  62.         Mov    CX,5            ; Number of delimiters (no /)
  63.         Repne    Scasb            ; See if a match
  64.         Je    NameSearch        ; If a delimiter, keep looking
  65.         Mov    DX,SI            ; Otherwise found file name
  66.         Dec    DX            ; Points to beginning of it
  67. EndSearch:    Lodsb                ; Get next byte
  68.         Cmp    AL,13            ; See if carriage return
  69.         Je    GotFileEnd        ; If so, we're all done
  70.         Mov    DI,Offset Delimiters    ; String of delimiters
  71.         Mov    CX,6            ; Number (including /)
  72.         Repne    Scasb            ; See if a match
  73.         Jne    EndSearch        ; If not, still in file name
  74.         Mov    Byte Ptr [SI - 1],0    ; If so, mark end of file name
  75.         Jcxz    GotFlag            ; If slash, check for W
  76.         Jmp    EndSearch        ; Or continue flag search
  77. GotFlag:    Lodsb                ; Get byte after / flag
  78.         Or    AL,20h            ; Uncapitalize
  79.         Cmp    AL,'w'            ; See if w for WordStar mode
  80.         Jnz    GotFileEnd        ; If not, just ignore it
  81.         Mov    [WSMode],7Fh        ; AND value for WordStar
  82.  
  83. ;    Open the File
  84. ;    -------------
  85.  
  86. GotFileEnd:    Mov    Byte Ptr [SI - 1],0    ; Mark end of file name
  87.                         ; DX still points to name
  88.         Mov    AX,3D00h        ; Open file for reading
  89.         Int    21h            ;   by calling DOS
  90.         Jnc    GotTheFile        ; If no error, continue    
  91. NoFileFound:    Mov    DX,Offset FileFail    ; Otherwise print a message 
  92.         Jmp    ErrorExit
  93. GotTheFile:    Mov    [FileHandle],AX        ; Save the file handle
  94.  
  95. ;    Get Screen Mode Information from BIOS Data Area
  96. ;    -----------------------------------------------
  97.  
  98.         Push    ES            ; Save register
  99.         Sub    AX,AX
  100.         Mov    ES,AX            ; Set ES to 0 (BIOS Data)
  101.         Mov    AL,ES:[0449h]        ; Current Video Mode
  102.  
  103. ;;;
  104.         CMP    WORD PTR ES:[0463H],03D4H    ; MONOCHROME EMULATION?
  105.         JZ    CHK_IF_TEXT            ; NO
  106.         MOV    [SCREENSEG],0B000H        ; ELSE ADDRESS MONO
  107.         MOV    [CHECKRETRACE],0        ; NO RETR. CHECK NEEDED
  108. CHK_IF_TEXT:
  109. ;;;
  110.  
  111.         Cmp    AL,3            ; Check if Color Alpha
  112.         Jbe    DisplayOK        ; Continue if so
  113.         Cmp    AL,7            ; Check if monochrome display
  114.         Je    Monochrome        ; If so, branch
  115. ;;;
  116.         MOV    AX,1A00H        ; VGA-ONLY BIOS CALL: READ
  117.         INT    10H            ;  DISPLAY COMBINATION CODE
  118.         CMP    AL,1AH            ; VGA ADAPTER?
  119.         JNZ    TO_SCREENFAIL        ; NO, SORRY
  120.         MOV    [CHECKRETRACE],0    ; ELSE NO RETRACE CHECK NEEDED
  121.         MOV    DX,3CEH
  122.         MOV    AL,6            ; READ BIT 0 OF THE VGA GRAPHICS
  123.         CLI                ;  CONTROLLER'S "MISCELLANEOUS"
  124.         OUT    DX,AL            ;  REGISTER AT PORT 3CEh, INDEX
  125.         INC    DX            ;  6.  IF BIT IS SET THEN WE'RE
  126.         JMP    SHORT $+2        ;  *REALLY* IN A GRAPHICS MODE
  127.         IN    AL,DX            ;
  128.         STI                ;
  129.         TEST    AL,1            ; WELL?
  130.         JZ    DISPLAYOK        ; OKAY, NOT SET = NOT GRAPHICS
  131. TO_SCREENFAIL:
  132. ;;;
  133.  
  134.         Mov    DX,Offset ScreenFail    ; We can't handle graphics
  135.         Jmp    ErrorExit        ; So print an error message
  136. Monochrome:    Mov    [ScreenSeg],0B000h    ; Use Monochrome Segment
  137.         Mov    [CheckRetrace],0    ; Don't have to check retrace
  138. DisplayOK:    Mov    AL,ES:[044Ah]        ; Number of Columns
  139.         Mov    [LineLength],AL        ; Save it
  140.         Mov    AX,ES:[044Eh]        ; Offset into screen buffer
  141.         Mov    [ScreenOff],AX        ; Save it         
  142.         Mov    AX,ES:[0463h]        ; Address of 6845 Regsiter
  143.         Mov    [Addr6845],AX        ; Save it
  144.         Push    ES
  145.         Sub    DL,DL            ; Set Rows to zero first
  146.         Sub    BH,BH
  147.         Mov    AX,1130h        ; EGA BIOS: Get Information
  148.         Int    10h
  149.         Pop    ES
  150.         Or    DL,DL            ; Check if DL is still zero
  151.         Jz    NoEGA            ; If so, skip rest of stuff
  152.         Inc    DL
  153.         Mov    [NumberLines],DL    ; Save Number of Lines
  154.         Test    Byte Ptr ES:[0487h],4    ; Check if must check retrace
  155.         Jnz    NoEGA
  156.         Mov    [CheckRetrace],0    ; EGA says we don't have to
  157. NoEGA:        Mov    BH,ES:[0462h]        ; Get Current Page (use later)
  158.         Pop    ES
  159.         Mov    AL,[LineLength]        ; Length of each line
  160.         Mul    [NumberLines]        ; Total chars on screen
  161.         Add    AX,AX            ; Double for attributes
  162.         Mov    [ScreenSize],AX        ; And Save it
  163.  
  164. ;    See if enough memory is left
  165. ;    ----------------------------
  166.  
  167.         Add    AX,Offset ScreenHold    ; Add ScreenSize to code end
  168.         Add    AX,256            ; Add a little stack room
  169.         Cmp    AX,SP            ; Check against stack pointer
  170.         Jbe    GotEnufMemory        ; Continue if OK
  171.         Mov    DX,Offset NoSpaceFail    ; Otherwise end program
  172.         Jmp    ErrorExit        ;    with error messae
  173.         
  174. ;    Get Current Screen Attribute
  175. ;    ---------------------------- 
  176.  
  177. GotEnufMemory:    Cmp    [Attribute],0        ; Check if attribute pre-set
  178.         Jnz    GotAttribute        ; If so, move on
  179.         Mov    DL,' '            ; Write out a byte
  180.         Mov    AH,2            ;   using DOS
  181.         Int    21h
  182.         Mov    AL,8            ; Now backspace
  183.         Mov    AH,14            ;   using BIOS call
  184.         Int    10h
  185.         Mov    AH,8            ; Read character & attribute
  186.         Int    10h            ;   using BIOS call (BH = pg)
  187.         Mov    [Attribute],AH        ; And save attribute
  188.  
  189. ;    Save Current Screen
  190. ;    -------------------
  191.  
  192. GotAttribute:    Mov    DX,Offset Terminate    ; Set Ctrl-Break exit
  193.         Mov    AX,2523h        ;   to terminate that way
  194.         Int    21h
  195.  
  196. ;;;
  197.  
  198. SAVE_CURSOR:    MOV    AH,0FH
  199.         INT    10H              ; VIDEO PAGE INTO BH
  200.         MOV    AH,3
  201.         INT    10H              ; READ CURSOR POSITION
  202.         JMP    SHORT SAVE_CURSOR_2
  203. SAVED_CURSOR    DW    0              ; STORAGE SPACE (A KLUDGE, I KNOW)
  204. SAVE_CURSOR_2:    MOV    SAVED_CURSOR,DX
  205.         MOV    AH,2
  206.         MOV    DX,-1
  207.         INT    10H              ; CURSOR TO TIMBUKTU FOR NOW
  208.  
  209. ;;;
  210.  
  211.         Mov    DI,Offset ScreenHold    ; Destination of screen
  212.         Mov    CX,[ScreenSize]        ; Size of screen
  213.         Push    DS            ; Save Source Segment
  214.         Lds    SI,[ScreenAddr]        ; Get screen address
  215.         Rep    Movsb            ; Move in the bytes
  216.         Pop    DS            ; Restore Source Segment
  217.  
  218. ;    Get Keyboard Key and Decide on Action
  219. ;    -------------------------------------
  220.  
  221.         Call    Home            ; Read file in
  222.         Mov    [ScreenStart],SI    ; Set buffer address
  223. KeyLoop:    Call    UpDateScreen        ; Write file to screen
  224. GetKey:        Mov    AH,8            ; Get key
  225.         Int    21h            ;   by calling DOS
  226.         Cmp    AL,27            ; Check if ESC
  227.         Je    Terminate        ; If so, terminate 
  228.         Cmp    AL,0            ; Check if extended
  229.         Jnz    GetKey            ; If not, try again
  230.         Mov    AH,8            ; Get extended code
  231.         Int    21h            ;   by calling DOS
  232.         Sub    AL,71            ; Subtract Home key value
  233.         Jb    GetKey            ; If below that, not valid
  234.         Cmp    AL,(81 - 71)        ; Check if above PgDn
  235.         Ja    GetKey            ; If so, ignore it
  236.         Sub    AH,AH            ; Zero out top byte
  237.         Add    AX,AX            ; Double for word access
  238.         Mov    BX,AX            ; Offset in dispatch table
  239.         Mov    SI,[ScreenStart]    ; Set current buffer pointer
  240.         Call    [Dispatch + BX]        ; Do the call
  241.         Mov    [ScreenStart],SI    ; Set new buffer pointer
  242.         Jmp    KeyLoop            ; And update the screen
  243.  
  244. ;    Terminate -- Restore screen and close file
  245. ;    ------------------------------------------
  246.  
  247. Terminate:    Mov    SI,Offset ScreenHold    ; Address of Saved Screen
  248.         Les    DI,[ScreenAddr]        ; Address of Display
  249.         Mov    CX,[ScreenSize]        ; Number of characters
  250.         Rep    Movsb            ; Move them back 
  251.         Mov    BX,[FileHandle]        ; Get File Handle
  252.         Mov    AH,3Eh            ; Close File
  253.         Int    21h
  254.  
  255. ;;;
  256.  
  257. RESTORE_CURSOR:    MOV    AH,0FH
  258.         INT    10H            ; VIDEO PAGE INTO BH
  259.         MOV    AH,2
  260.         MOV    DX,SAVED_CURSOR
  261.         INT    10H            ; RESTORE ENTRY CURSOR POSITION
  262. ;;;
  263.  
  264.         Int    20h            ; Terminate
  265.  
  266. ;    Cursor Key Routines -- Home Key
  267. ;    -------------------------------
  268.  
  269. Home:        Sub    BX,BX            ; For zeroing out values
  270.         Mov    AX,[FileOffset]        ; Check if read in file
  271.         Or    AX,[FileOffset + 2]
  272.         Mov    [FileOffset],BX        ; Zero out file address
  273.         Mov    [FileOffset + 2],BX
  274.         Mov    [HorizOffset],BX    ; Zero out horizontal offset    
  275.         Mov    SI,Offset Buffer    ; Reset buffer pointer    
  276.         Jz    Dummy            ; Skip file read if in already
  277.         Mov    DX,Offset Buffer    ; Area to read file in
  278.         Mov    CX,32768        ; Number of bytes to read
  279.         Call    FileRead        ; Read in file
  280. Dummy:        Ret
  281.  
  282. ;    Up and PgUp Keys
  283. ;    ----------------
  284.  
  285. Up:        Call    GetPrevChar        ; Get previous char in buffer
  286.         Jc    UpDone            ; If none available, finish
  287. UpLoop:        Call    GetPrevChar        ; Get previous char again
  288.         Jc    UpDone            ; if none, we're done
  289.         Cmp    AL,10            ; Check if line feed
  290.         Jnz    UpLoop            ; If not, try again 
  291.         Call    GetNextChar        ; Get char after line feed
  292. UpDone:        Ret
  293.  
  294. PgUp:        Mov    CX,Word Ptr [NumberLines]    ; Number of lines
  295. PgUpLoop:    Call    Up            ; Do UP that many times
  296.         Loop    PgUpLoop
  297.         Ret
  298.  
  299. ;    Left and Right Keys
  300. ;    -------------------
  301.  
  302. Left:        Mov    [HorizOffset],0        ; Reset Horizontal Offset
  303.         Ret
  304.  
  305. Right:        Mov    AL,[ShiftHoriz]        ; Get places to shift
  306.         Sub    AH,AH
  307.         Add    [HorizOffset],AX    ; Move that many right
  308.         Ret
  309.  
  310. ;    End, Down, and PgDn Keys
  311. ;    ------------------------
  312.  
  313. EndKEY:        Mov    BX,SI            ; Save buffer pointer
  314.         Call    PgDn            ; Go page down
  315.         Cmp    BX,SI            ; Check if we did so
  316.         Jnz    EndKEY            ; If so, do it again
  317.         Ret
  318.  
  319. Down:        Call    GetNextChar        ; Get next character
  320.         Jc    NoMoreDown        ; If no more, we're done
  321. DownLoop:    Call    GetNextChar        ; Get one again
  322.         Jc    UpLoop            ; If no more, find prev LF
  323.         Cmp    AL,10            ; See if line feed
  324.         Jnz    DownLoop        ; If not, continue
  325. NoMoreDown:    Ret
  326.  
  327. PgDn:        Mov    CX,Word Ptr [NumberLines]    ; Number of lines
  328. PgDnLoop:    Call    Down            ; Do DOWN that many times
  329.         Loop    PgDnLoop
  330.         Ret
  331.  
  332. ;    Update Screen
  333. ;    -------------
  334.  
  335. UpdateScreen:    Push    ES
  336.         Mov    SI,[ScreenStart]    ; Address of data in buffer
  337.         Les    DI,[ScreenAddr]        ; Address of display
  338.         Mov    CX,ScreenSize        ; Number of bytes in screen
  339.         Shr    CX,1            ; Half for number of chars
  340.         Mov    AL,' '            ; Will blank screen
  341.         Mov    AH,[Attribute]        ; With screen attribute
  342.         Rep    Stosw            ; Blank it
  343.         Mov    AL,[LineLength]        ; Length of display line
  344.         Sub    AH,AH
  345.         Add    AX,[HorizOffset]    ; Add Horizontal Offset
  346.         Mov    [RightMargin],AX    ; That's right display margin
  347.         Sub    DL,DL            ; Line Number
  348. LineLoop:    Sub    BX,BX            ; Column Number
  349.         Mov    AL,[LineLength]        ; Use Line Length
  350.         Mul    DL            ;   and Line Number
  351.         Add    AX,AX            ;     to recalculate
  352.         Mov    DI,AX            ;       display destination
  353.         Add    DI,[ScreenOff]        ; Add beginning address    
  354. CharLoop:    Call    GetNextChar        ; Get next character
  355.         Jc    EndOfScreen        ; If no more, we're done
  356.         And    AL,[WSMode]        ; Will be 7Fh for WordStar
  357.         Cmp    AL,13            ; Check for carriage return
  358.         Je    CharLoop        ; Do nothing if so
  359.         Cmp    AL,10            ; Check for line feed
  360.         Je    LineFeed        ; Do routine if so
  361.         Cmp    AL,9            ; Check for tab
  362.         Je    Tab            ; Do routine if so
  363.         Mov    CX,1            ; Just 1 char to display
  364. PrintChar:    Cmp    BX,[HorizOffset]    ; See if we can print it
  365.         Jb    NoPrint        
  366.         Cmp    BX,[RightMargin]    ; See if within margin
  367.         Jae    NoPrint
  368.         Mov    AH,[Attribute]        ; Attribute for display
  369.         Cmp    [CheckRetrace],0    ; See if must stop snow
  370.         Jz    WriteIt            ; If not, skip retrace wait
  371.         Push    BX
  372.         Push    DX
  373.         Mov    BX,AX            ; Save character and attribute
  374.         Mov    DX,[Addr6845]        ; Set up I/O address
  375.         Add    DX,6 
  376. RetraceWait1:    In    AL,DX            ; Check until
  377.         Shr    AL,1            ;   vertical retrace
  378.         Jc    RetraceWait1        ;     ends
  379.         Cli                ; Clear interrupts
  380. RetraceWait2:    In    AL,DX            ; Check until
  381.         Shr    AL,1            ;   vertical retrace
  382.         Jnc    RetraceWait2        ;     begins
  383.         Mov    AX,BX            ; Get back character & attr
  384.         Stosw                ; Write to display
  385.         Sti                ; Enable interrupts again
  386.         Pop    DX
  387.         Pop    BX
  388.         Jmp    Short NoPrint        ; Skip around "no snow" write
  389. WriteIt:    Stosw                ; Write without retrace wait
  390. NoPrint:    Inc    BX            ; Bump up line counter
  391.         Loop    PrintChar        ; Do it CX times
  392.         Jmp    CharLoop        ; Then go back to top
  393. Tab:        Mov    AX,BX            ; Current column number
  394.         And    AX,07h            ; Take lower three bits
  395.         Mov    CX,8
  396.         Sub    CX,AX            ; Subtract from 8
  397.         Mov    AL,' '            ; Will print CX blanks
  398.         Jmp    PrintChar
  399. LineFeed:    Inc    DL            ; Next line
  400.         Cmp    DL,[NumberLines]    ; See if down at bottom
  401.         Jb    LineLoop        ; If not, continue
  402. EndOfScreen:    Pop    ES            ; All done -- leave
  403.         Ret
  404.  
  405. ;    Get Next Character from buffer
  406. ;    ------------------------------
  407. ;        (Input is SI pointing to buffer, Returns AL, CY if no more)
  408.  
  409. GetNextChar:    Cmp    SI,[EndOfFile]        ; See if at end of file
  410.         Jae    NoMoreNext        ; If so, no more chars
  411.         Cmp    SI,Offset BufferEnd    ; See if at end of buffer
  412.         Jb    CanGetNext        ; If not, just get character
  413.         Push    CX            ; Otherwise save registers
  414.         Push    DX
  415.         Push    DI
  416.         Push    ES
  417.         Push    DS            ; Set ES to DS
  418.         Pop    ES            ;   (could be different)
  419.         Mov    SI,Offset BufferMid    ; Move 2nd buffer half
  420.         Mov    DI,Offset Buffer    ;   to 1st buffer half    
  421.         Mov    CX,16384       
  422.         Sub    [ScreenStart],CX    ; New buffer pointer
  423.         Rep    Movsb            ; Move them
  424.         Mov    SI,DI            ; SI also buffer pointer
  425.         Add    [FileOffset],32768     ; Adjust file addr to read
  426.         Adc    [FileOffset + 2],0 
  427.         Mov    DX,Offset BufferMid    ; Place to read file
  428.         Mov    CX,16384        ; Number of bytes
  429.         Call    FileRead        ; Read the file
  430.         Sub    [FileOffset],16384    ; Now adjust so reflects
  431.         Sbb    [FileOffset + 2],0    ;   1st half of buffer
  432.         Pop    ES            ; Get back registers
  433.         Pop    DI
  434.         Pop    DX
  435.         Pop    CX
  436.         Jmp    GetNextChar        ; And try again to get char
  437. CanGetNext:    Lodsb                ; Get the character
  438. NoMoreNext:    Cmc                ; So CY set if no more
  439.         Ret                
  440.  
  441. ;    Get Previous Character from buffer
  442. ;    ----------------------------------
  443.  
  444. GetPrevChar:    Cmp    SI,Offset Buffer    ; See if at top of buffer
  445.         Ja    CanGetPrev        ; If not, just get character
  446.         Mov    AX,[FileOffset]        ; See if at top of file
  447.         Or    AX,[FileOffset + 2]
  448.         Jz    AtTopAlready        ; If so, can't get anymore
  449.         Push    CX            ; Save some registers
  450.         Push    DX
  451.         Mov    SI,Offset Buffer    ; Move 1st half of buffer
  452.         Mov    DI,Offset BufferMid    ;   to 2nd half of buffer
  453.         Mov    CX,16384
  454.         Add    [ScreenStart],CX    ; New buffer pointer
  455.         Rep    Movsb            ; Do the move
  456.         Sub    [FileOffset],16384    ; Adjust file addr for read
  457.         Sbb    [FileOffset + 2],0
  458.         Mov    DX,Offset Buffer    ; Area to read file into
  459.         Mov    CX,16384        ; Number of bytes
  460.         Call    FileRead        ; Read the file
  461.         Pop    DX            ; Get back registers
  462.         Pop    CX
  463.         Jmp    Short CanGetPrev    ; Now get character
  464. AtTopAlready:    Stc                ; CY flag set for no more
  465.         Ret
  466. CanGetPrev:    Dec    SI            ; Move pointer back
  467.         Mov    AL,[SI]            ; Get the character
  468.         Clc                ; CY flag reset for success
  469.         Ret
  470.  
  471. ;    Read CX bytes from the file into DX buffer
  472. ;    ------------------------------------------     
  473.  
  474. FileRead:    Push    AX            ; Save some registers
  475.         Push    BX
  476.         Push    CX
  477.         Push    DX
  478.         Mov    [EndOfFile],-1        ; Initialize this
  479.         Mov    DX,[FileOffset]        ; Get file address to read
  480.         Mov    CX,[FileOffset + 2]
  481.         Mov    BX,[FileHandle]        ; Get file Handle
  482.         Sub    AL,AL            ; Do LSEEK from beginning
  483.         Mov    AH,42h            ; LSEEK call
  484.         Int    21h
  485.         Pop    DX            ; Get back destination
  486.         Pop    CX            ; Get back count
  487.         Mov    AH,3Fh            ; Read file function call
  488.         Int    21h
  489.         Jnc    NoReadError        ; If no error, continue
  490.         Sub    AX,AX            ; Otherwise read zero bytes
  491. NoReadError:    Cmp    AX,CX            ; See if 32K has been read
  492.         Je    GotItAll        ; If so, we're home free
  493.         Add    AX,DX            ; Otherwise add to buffer addr
  494.         Mov    [EndOfFile],AX        ; And save as end of file
  495. GotItAll:    Pop    BX
  496.         Pop    AX
  497.         Ret
  498.  
  499. ;    File Buffer and Screen Hold Areas
  500. ;    ---------------------------------
  501.  
  502. Buffer        Label    Byte            ; Area for file reads
  503. BufferMid    equ    Buffer + 16384        ; Halfway through it
  504. BufferEnd    equ    BufferMid + 16384    ; At end of it        
  505. ScreenHold    equ    BufferEnd        ; Area for holding screen
  506. CSEG        EndS                ; End of segment
  507.         End    Entry            ; Denotes entry point
  508.